// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: linchuan

#pragma once

#include <cstdio>
#include <memory>
#include <set>
#include <string>
#include <string_view>

#include <rapidjson/document.h>

#include "coin2/exchange/base/order/order.h"
#include "coin2/exchange/bitmex/symbology/currency.h"
#include "coin2/exchange/bitmex/symbology/product.h"

namespace coin2::exchange::bitmex::order_v1 {

class BitmexParser : public base::order::BaseParser {
 public:
  const ParseResult& ParseRawMessage(const RawMessage& msg) override;
  AccountBalance ParseBalance(const JsonValue& doc) override;
  AccountPosition ParsePosition(const JsonValue& doc) override;
  bool ParseRawBalance(const JsonValue& doc, RawBalanceMap* raw_balance_map);
  bool ParseRawPosition(const JsonValue& doc, RawPositionMap* raw_position_map);

 private:
  void ParseSubmitResponse();
  void ParseCancelResponse();
  void ParseRestOrdersInfo();
  void ParseRestFillInfoList();
  void ParseRestAccountBalance();
  void ParseRestAccountPosition();
  void ParseWsMessage();

  AccountBalance ParseWsBalance(const JsonValue& doc);
  AccountPosition ParseWsPosition(const JsonValue& doc);
  ProductOrderBundle ParseWsOrderInfoListV2(const JsonValue& data);
  ProductFillBundle ParseWsFillInfoListV2(const JsonValue& data);

  coin::proto::ProductOrderElement ParseOrderInfo(const JsonValue& data);
  coin::proto::ProductOrderElement ParseWsOrderInfo(const JsonValue& data);
  void SetProductFillBundleFromRaw(const JsonValue& data, ProductFillBundle* product_fill_bundle);

  auto GetMultiplier(std::string_view native_currency) -> int64_t {
    if (native_currency == "USDT") {
      return 1e6;
    }
    return 1e8;
  }

 private:
  bool ignorable_ws_update_ = false;
  bool is_account_balance_initialized_ = false;
  bool is_account_position_initialized_ = false;
};

}  // namespace coin2::exchange::bitmex::order_v1
